# Copyright 2021 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluent-bit
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: fluent-bit-read
rules:
  - apiGroups: [""]
    resources:
      - namespaces
      - pods
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fluent-bit-read
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluent-bit-read
subjects:
  - kind: ServiceAccount
    name: fluent-bit
    namespace: default
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluent-bit-config
  namespace: default
  labels:
    k8s-app: fluent-bit
data:
  # Configuration files: server, input, filters and output
  # ======================================================
  fluent-bit.conf: |
    [SERVICE]
        Flush         1
        Grace         30
        Log_Level     info
        Daemon        off
        Parsers_File  parsers.conf
        HTTP_Server   Off
        Config_Watch  Off

    @INCLUDE input-kubernetes.conf
    @INCLUDE filter-kubernetes.conf
    @INCLUDE filter-k8s-events.conf
    @INCLUDE filter-stackdriver-format.conf
    @INCLUDE output.conf

  input-kubernetes.conf: |
    [INPUT]
        Name              tail
        Tag               kube.*
        Path              /var/log/containers/*.log
        Parser            docker
        DB                /var/log/flb_kube.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10

  filter-kubernetes.conf: |
    [FILTER]
        Name                kubernetes
        Match               kube.var.log.containers.*
        Kube_URL            https://kubernetes.default.svc:443
        Kube_Tag_Prefix     kube.var.log.containers.
        Merge_Log           On

    # this retagging helps stackdriver and it doesn't matter for cloudwatch
    # https://docs.fluentbit.io/manual/pipeline/outputs/stackdriver#configuration-file
    [FILTER]
        Name rewrite_tag
        Match kube.var.log.containers.*
        Rule $log ^(.*)$ k8s_container.$kubernetes['namespace_name'].$kubernetes['pod_name'].$kubernetes['container_name'] false

    [FILTER]
        Name                modify
        Match               k8s_container.*
        Condition           Key_Exists message
        Hard_rename         message log

    [FILTER]
        Name                nest
        Match               k8s_container.*
        Operation           lift
        Nested_under        kubernetes
        Add_prefix          k8s.

    [FILTER]
        Name                modify
        Match               k8s_container.*
        Condition           Key_Does_Not_Exist labels
        Rename              k8s.labels labels

    [FILTER]
        Name                modify
        Match               k8s_container.*
        Remove_wildcard     k8s.

  filter-k8s-events.conf: |
    [FILTER]
        Name                nest
        Match               k8s_container.*.event-exporter-*
        Operation           lift
        Nested_under        involvedObject
        Add_prefix          involvedObject.

    [FILTER]
        Name                modify
        Match               k8s_container.*.event-exporter-*
        Condition           Key_exists labels
        Rename              labels k8s.labels

    [FILTER]
        Name                modify
        Match               k8s_container.*.event-exporter-*
        Condition           Key_exists involvedObject.labels
        Hard_copy           involvedObject.labels labels

    [FILTER]
        Name                nest
        Match               k8s_container.*.event-exporter-*
        Operation           nest
        Wildcard            involvedObject.*
        Nest_under          involvedObject
        Remove_prefix       involvedObject.

  filter-stackdriver-format.conf: |
    [FILTER]
        Name                modify
        Match               k8s_container.*
        Condition           Key_exists log
        Rename              log message

    [FILTER]
        Name                modify
        Match               k8s_container.*
        Condition           Key_exists levelname
        Rename              levelname level

  output.conf: |
    [OUTPUT]
        Name              cloudwatch
        Match             k8s_container.*
        region            {{ config["region"] }}
        log_group_name    {{ config["cluster_name"] }}
        log_stream_prefix kube.
        auto_create_group true

  parsers.conf: |
    [PARSER]
        Name        docker
        Format      json
        Time_Key    time
        Time_Format %Y-%m-%dT%H:%M:%S.%L
        Time_Keep   On
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: default
spec:
  selector:
    matchLabels:
      k8s-app: fluent-bit-logging
  template:
    metadata:
      labels:
        app: fluent-bit
        k8s-app: fluent-bit-logging
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
        - name: fluent-bit
          image: {{ config["image_fluent_bit"] }}
          imagePullPolicy: Always
          resources:
            requests:
              cpu: 100m
              memory: 150Mi
            limits:
              cpu: 150m
              memory: 150Mi
          ports:
            - containerPort: 2020
          volumeMounts:
            - name: varlog
              mountPath: /var/log
            - name: varlibdockercontainers
              mountPath: /var/lib/docker/containers
              readOnly: true
            - name: fluent-bit-config
              mountPath: /fluent-bit/etc/
      terminationGracePeriodSeconds: 60
      volumes:
        - name: varlog
          hostPath:
            path: /var/log
        - name: varlibdockercontainers
          hostPath:
            path: /var/lib/docker/containers
        - name: fluent-bit-config
          configMap:
            name: fluent-bit-config
      serviceAccountName: fluent-bit
      tolerations:
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule
        - operator: "Exists"
          effect: "NoExecute"
        - operator: "Exists"
          effect: "NoSchedule"
        - key: aws.amazon.com/neuron
          operator: Exists
          effect: NoSchedule
        - key: nvidia.com/gpu
          operator: Exists
          effect: NoSchedule
        - key: workload
          operator: Exists
          effect: NoSchedule
